﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Configuration;
using System.Web.Security;
using System.Threading;

using OnlineFamilyCalendar.Common.Configuration;
using OnlineFamilyCalendar.Common.Security;

namespace OnlineFamilyCalendar.UI.Web.AuthenticationModule
{
    class AuthenticationModule : IHttpModule
    {
        private OnlineFamilyCalendarAuthenticationSection _config;

        public AuthenticationModule()
        {
            _config = (OnlineFamilyCalendarAuthenticationSection)ConfigurationManager.GetSection("onlineFamilyCalendarAuthentication");
        }

        public void Init(HttpApplication context)
        {
            context.AuthenticateRequest += new EventHandler(this.AuthenticateRequestHandler);            
        }

        private void AuthenticateRequestHandler(object sender, EventArgs e)
        {
            HttpApplication httpApplication = (HttpApplication)sender;
            HttpRequest request = httpApplication.Request;
            HttpResponse response = httpApplication.Response;

            string loginUrl = _config.LoginUrl;
            string registerUrl = _config.RegisterUrl;
            string cookieName = _config.CookieName;

            HttpCookie secureCookie = request.Cookies[cookieName];
            if (secureCookie == null)
            {
                if (IsPublicUrl(request, loginUrl) || IsPublicUrl(request, registerUrl))
                    return;
                else
                    response.Redirect(request.ApplicationPath + loginUrl, true);
            }

            HttpCookie authCookie = null;
            try
            {
                authCookie = HttpSecureCookie.Decode(secureCookie);
            }
            catch (InvalidCypherTextException ex)
            {
                // ToDo Log Exception
                secureCookie.Expires = DateTime.Now.AddDays(-1);
                response.Cookies.Add(secureCookie);
                response.Redirect(request.ApplicationPath + loginUrl, true);
            }

            OnlineFamilyCalendarIdentity identity = Authentication.DeserializeIdentity(authCookie.Value);
            OnlineFamilyCalendarPrincipal principal = new OnlineFamilyCalendarPrincipal(identity, identity.Role);

            httpApplication.Context.User = principal;
            Thread.CurrentPrincipal = principal;

            secureCookie.Expires = DateTime.Now.AddMinutes(_config.CookieExpiration);
            response.Cookies.Add(secureCookie);
        }

        private bool IsPublicUrl(HttpRequest httpRequest, string url)
        {
            if (String.Compare(httpRequest.Path.Remove(0, 1), url, true) == 0)
                return true;
            else
                return false;
        }

        public void Dispose()
        {
        }
    }
}
